package com.qianniu.napi.admin.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.qianniu.napi.admin.entity.Jifen;
import com.qianniu.napi.admin.entity.JifenFlow;
import com.qianniu.napi.admin.entity.User;
import com.qianniu.napi.admin.entity.penum.IotypeEnum;
import com.qianniu.napi.admin.entity.penum.JftypeEnum;
import com.qianniu.napi.admin.entity.penum.XftypeEnum;
import com.qianniu.napi.admin.mapper.JifenFlowMapper;
import com.qianniu.napi.admin.mapper.JifenMapper;
import com.qianniu.napi.admin.service.IJifenFlowService;
import com.qianniu.napi.admin.service.IJifenService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.qianniu.napi.admin.service.IUserService;
import com.qianniu.napi.admin.service.akka.SignActor;
import com.qianniu.napi.common.util.DateUtil;
import com.qianniu.napi.common.util.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 积分表 服务实现类
 * </p>
 *
 * @author chenxuebin
 * @since 2018-09-04
 */
@Service
public class JifenServiceImpl extends ServiceImpl<JifenMapper, Jifen> implements IJifenService {

    private final static Logger logger = LoggerFactory.getLogger(JifenServiceImpl.class);

    @Autowired
    JifenMapper jifenMapper;
    @Autowired
    JifenFlowMapper JifenFlowMapper;
    @Autowired
    IJifenFlowService jifenFlowService;
    @Autowired
    IUserService userService;

    public void addJifenFlow(Long uid, Long mid, Long mpid, BigDecimal num,
                             Boolean isconfirm, Integer fantimeType,
                             String sn, IotypeEnum iotype, JftypeEnum xftype, String remark,Long ywid) {

        if(uid==null){
            logger.error("===================addJifenFlow pass uid=null");
            return;
        }
        JifenFlow jf = new JifenFlow();
        // *******  客户消耗  *******
        jf.setNum(num);
        jf.setSn(sn);// 抵扣积分时 = 订单号
        jf.setIotype(iotype.getVal());//积分消费
        jf.setJftype(xftype.getVal());//积分消费
        jf.setFantimeType(fantimeType);
        jf.setCreatetime(new Date());
        jf.setUid(uid);
        jf.setMid(mid);
        jf.setMpid(mpid);
        jf.setRemark(remark);
        jf.setIsConfirm(isconfirm?1:-1);
        if(isconfirm)jf.setConfirmDate(new Date());
        jf.setState(xftype.getVal()==JftypeEnum.duihuan.getVal()?0:1);
        jf.setYwid(ywid);
        jf.insert();

        Jifen jifen = null;

        Boolean flag = false;
        while (!flag) {
            List<Jifen> jifens = jifenMapper.selectList(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifens == null||jifens.size()==0) jifen = initJifen(uid, mid, mpid);
            else jifen = jifens.get(0);

            long v = jifen.getVersion();

            BigDecimal total = iotype.getVal() == 1 ? jifen.getTotal().add(jf.getNum()) : jifen.getTotal().subtract(jf.getNum());
            BigDecimal fanliing = iotype.getVal() == 1 ? jifen.getFanliing().add(jf.getNum()) : jifen.getFanliing().subtract(jf.getNum());

            if (isconfirm) jifen.setTotal(total);
            else jifen.setFanliing(fanliing);

            jifen.setVersion(jifen.getVersion() + 1);
            jifen.setModifytime(new Date());
            jifen.setModifier(uid);
            int m = jifenMapper.update(jifen, new EntityWrapper<Jifen>().eq("version", v).eq("uid", uid));
            logger.debug(">>>jifenMapper.update m=" + m);
            flag = m>0;
        }
    }

    public void addJifenFlow(Long uid, Long mid, Long mpid, BigDecimal num,
                             Boolean isconfirm, BigDecimal money,
                             String sn, IotypeEnum iotype, JftypeEnum xftype, String remark,Long ywid) {

        if(uid==null){
            logger.error("===================addJifenFlow pass uid=null");
            return;
        }
        JifenFlow jf = new JifenFlow();
        // *******  客户消耗  *******
        jf.setNum(num);
        jf.setSn(sn);// 抵扣积分时 = 订单号
        jf.setIotype(iotype.getVal());//积分消费
        jf.setJftype(xftype.getVal());//积分消费
        jf.setMoney(money);
        jf.setCreatetime(new Date());
        jf.setUid(uid);
        jf.setMid(mid);
        jf.setMpid(mpid);
        jf.setRemark(remark);
        jf.setIsConfirm(isconfirm?1:-1);
        if(isconfirm)jf.setConfirmDate(new Date());
        jf.setState(xftype.getVal()==JftypeEnum.duihuantx.getVal()?0:1);
        jf.setYwid(ywid);
        jf.insert();

        Jifen jifen = null;

        Boolean flag = false;
        while (!flag) {
            List<Jifen> jifens = jifenMapper.selectList(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifens == null||jifens.size()==0) jifen = initJifen(uid, mid, mpid);
            else jifen = jifens.get(0);

            long v = jifen.getVersion();

            BigDecimal total = iotype.getVal() == 1 ? jifen.getTotal().add(jf.getNum()) : jifen.getTotal().subtract(jf.getNum());
            BigDecimal fanliing = iotype.getVal() == 1 ? jifen.getFanliing().add(jf.getNum()) : jifen.getFanliing().subtract(jf.getNum());

            if (isconfirm) jifen.setTotal(total);
            else jifen.setFanliing(fanliing);

            jifen.setVersion(jifen.getVersion() + 1);
            jifen.setModifytime(new Date());
            jifen.setModifier(uid);
            int m = jifenMapper.update(jifen, new EntityWrapper<Jifen>().eq("version", v).eq("uid", uid));
            logger.debug(">>>jifenMapper.update m=" + m);
            flag = m>0;
        }
    }

    public void addJifenFlowOffline(Long uid, Long mid, Long mpid, BigDecimal num,
                             Boolean isconfirm, BigDecimal money,
                             String sn, IotypeEnum iotype, JftypeEnum xftype, String remark,Long ywid,Boolean offline) {

        if(uid==null){
            logger.error("===================addJifenFlow pass uid=null");
            return;
        }
        JifenFlow jf = new JifenFlow();
        // *******  客户消耗  *******
        jf.setNum(num);
        jf.setSn(sn);// 抵扣积分时 = 订单号
        jf.setIotype(iotype.getVal());//积分消费
        jf.setJftype(xftype.getVal());//积分消费
        jf.setMoney(money);
        jf.setCreatetime(new Date());
        jf.setUid(uid);
        jf.setMid(mid);
        jf.setMpid(mpid);
        jf.setRemark(remark);
        jf.setIsConfirm(isconfirm?1:-1);
        if(isconfirm)jf.setConfirmDate(new Date());
        jf.setState(offline&&xftype.getVal()==JftypeEnum.duihuantx.getVal()?0:1);
        jf.setYwid(ywid);
        jf.insert();

        Jifen jifen = null;

        Boolean flag = false;
        while (!flag) {
            List<Jifen> jifens = jifenMapper.selectList(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifens == null||jifens.size()==0) jifen = initJifen(uid, mid, mpid);
            else jifen = jifens.get(0);

            long v = jifen.getVersion();

            BigDecimal total = iotype.getVal() == 1 ? jifen.getTotal().add(jf.getNum()) : jifen.getTotal().subtract(jf.getNum());
            BigDecimal fanliing = iotype.getVal() == 1 ? jifen.getFanliing().add(jf.getNum()) : jifen.getFanliing().subtract(jf.getNum());

            if (isconfirm) jifen.setTotal(total);
            else jifen.setFanliing(fanliing);

            jifen.setVersion(jifen.getVersion() + 1);
            jifen.setModifytime(new Date());
            jifen.setModifier(uid);
            int m = jifenMapper.update(jifen, new EntityWrapper<Jifen>().eq("version", v).eq("uid", uid));
            logger.debug(">>>jifenMapper.update m=" + m);
            flag = m>0;
        }
    }

    public Boolean jifenFlowConfirm(String sn,Long uid){

        JifenFlow jf = jifenFlowService.selectOne(new EntityWrapper<JifenFlow>().eq("sn", sn));
        boolean flag = false;
        int upcout = 0;
        Jifen jifen = null;
        Jifen njifen = new Jifen();
        while (jf != null && !flag) {
            List<Jifen> jifens = jifenMapper.selectList(new EntityWrapper<Jifen>().eq("uid", uid));
            if (jifens == null||jifens.size()==0) {
                logger.debug("------------account at uid=" + uid + " not exist and sn=" + sn);
                logger.debug("------------start to init jifen");
                jifen = initJifen(uid);
            }
            else{
                jifen = jifens.get(0);
            }
            if(jifen==null){
                break;
            }
            jf.setIsConfirm(1);
            jf.setConfirmDate(new Date());
            jf.setModifytime(new Date());
            jf.setModifier(uid);

            long version = jifen.getVersion();
            BigDecimal total = jifen.getTotal();

            njifen.setTotal(jf.getIotype() == 1 ? total.add(jf.getNum()) : total.subtract(jf.getNum()));
            njifen.setModifytime(new Date());
            njifen.setModifier(uid);
            njifen.setVersion(version + 1);

            upcout = jifenMapper.update(njifen, new EntityWrapper<Jifen>().eq("uid", uid).eq("version", version));
            if (upcout>0){
                flag = true;
                jf.insertOrUpdate();
            }
        }
        return flag;
    }

    public Jifen initJifen(){
        BigDecimal zero = new BigDecimal(0);
        Jifen jifen = new Jifen();
        jifen.setTotal(zero);
        jifen.setState(1);
        jifen.setVersion(1l);
        jifen.setUid(ObjectUtil.getUid());
        jifen.setMid(ObjectUtil.getMid());
        jifen.setMpid(ObjectUtil.getMpid());
        jifen.setCreatetime(new Date());
        jifen.insert();

        return jifen;
    }

    public Jifen initJifen(Long uid) {
        User user = userService.selectById(uid);
        if(user==null) return null;
        return initJifen(uid,user.getMid(),user.getMpid());
    }

    public Jifen initJifen(Long uid, Long mid, Long mpid) {
        BigDecimal zero = new BigDecimal(0);

        Jifen act = new Jifen();
        act.setUid(uid);
        act.setMid(mid);
        act.setMpid(mpid);

        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setTotal(zero);
        act.setFanliing(zero);
        act.setState(1);
        act.insert();
        return act;
    }

}
